#include "rtspwidget.h"
#include "MessageBox.h"
#include "models/command.h"
#include "models/operatelogmodel.h"
#include "models/robot.h"
#include "public/public.h"
#include <QAudioOutput>
#include <QTime>
#include <qpainter.h>
#include<QTimer>
#include <QVBoxLayout>
#include "UserMenu.h"
#include "MainWindow.h"
#include "models/robotlist.h"


RtspWidget::RtspWidget(QWidget *parent)
    : VideoBase(parent)
{
    setAttribute(Qt::WA_StyledBackground, true);  // 允许 Widget 使用样式表设置背景
    setStyleSheet(" background-color: rgb(0, 0, 0);border: 0px; ");
    VideoBase::connect(&m_rtspThread, &RtspThread::connecting, this, &VideoBase::onConnecting);
    VideoBase::connect(&m_rtspThread, &RtspThread::connectFail, this, &VideoBase::onConnectFail);
    VideoBase::connect(&m_rtspThread, &RtspThread::connectSucc, this, [this](){VideoBase::onConnectSucc();});
    VideoBase::connect(&m_rtspThread, &RtspThread::recordEnd, this, &VideoBase::onRecordEnd);
    VideoBase::connect(&m_rtspThread, &RtspThread::updateFrame, this, [this](QImage * img){
        if(img)
        {
            m_lockFrame.lock();
            m_frame = img->copy();
            m_lockFrame.unlock();
            m_bPlaySucc = true;
        }
        QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
    },Qt::DirectConnection);
    m_pSentryWidget = new QWidget(this);
    m_pSentryWidget->setStyleSheet("background-color:transparent");
    m_pIdentifyBtn = new TouchButton(m_pSentryWidget);
    m_pIdentifyBtn->setText("");
    m_pIdentifyBtn->setFixedSize(60*g_xScale,60*g_xScale);
    m_pIdentifyBtn->setCheckable(true);
    m_pIdentifyBtn->setStyleSheet("QPushButton { border-image:url(:/images/identify.png); } QPushButton:checked {  border-image:url(:/images/identify.png); }");
    connect(m_pIdentifyBtn,&QPushButton::clicked,this,[this](){
        QStringList lsBtns;
        lsBtns << tr("识别人") << tr("识别车");
        UserMenu *menu = new UserMenu(lsBtns, this);
        // 计算菜单显示位置
        QPoint pt = m_pIdentifyBtn->mapToGlobal(QPoint(0,m_pIdentifyBtn->height()/2));
        QSize menuSize = menu->sizeHint();
        menu->move(pt.x() - menuSize.width(), pt.y() - menuSize.height()/2);
        // 显示菜单并处理结果
        int result = menu->exec();
        delete menu;
        if (result > 0) {
            Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
            if(pCurRobot)
                pCurRobot->sentryIndify(result);
        }
    });

    m_pTrackBtn = new TouchButton(m_pSentryWidget);
    m_pTrackBtn->setText("");
    m_pTrackBtn->setFixedSize(60*g_xScale,60*g_xScale);
    m_pTrackBtn->setCheckable(true);
    m_pTrackBtn->setStyleSheet("QPushButton { border-image:url(:/images/track.png); } QPushButton:checked {  border-image:url(:/images/track.png); }");
    connect(m_pTrackBtn,&QPushButton::clicked,this,[this](){
        QStringList lsBtns;
        lsBtns << tr("第一路") << tr("第二路");
        UserMenu *menu = new UserMenu(lsBtns, this);
        // 计算菜单显示位置
        QPoint pt = m_pTrackBtn->mapToGlobal(QPoint(0,m_pTrackBtn->height()/2));
        QSize menuSize = menu->sizeHint();
        menu->move(pt.x() - menuSize.width(), pt.y() - menuSize.height()/2);
        // 显示菜单并处理结果
        int result = menu->exec();
        delete menu;
        if (result > 0) {
            Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
            if(pCurRobot)
                pCurRobot->sentryTrack(result);
        }
    });
    m_pGetRetBtn = new TouchButton(m_pSentryWidget);
    m_pGetRetBtn->setText("");
    m_pGetRetBtn->setFixedSize(60*g_xScale,60*g_xScale);
    m_pGetRetBtn->setCheckable(true);
    m_pGetRetBtn->setStyleSheet("QPushButton { border-image:url(:/images/get_ret.png); } QPushButton:checked {  border-image:url(:/images/get_ret.png); }");
    connect(m_pGetRetBtn,&QPushButton::clicked,this,[this](){
        Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
        if(pCurRobot)
        {
            pCurRobot->sentryGetResult();
            m_bGetRet = true;
        }
    });


    m_pLaserBtn = new TouchButton(m_pSentryWidget);
    m_pLaserBtn->setText("");
    m_pLaserBtn->setFixedSize(60*g_xScale,60*g_xScale);
    m_pLaserBtn->setCheckable(true);
    m_pLaserBtn->setStyleSheet("QPushButton { border-image:url(:/images/slam_rang.png); } QPushButton:pressed {  border-image:url(:/images/slam_rang_select.png); }");
    connect(m_pLaserBtn,&QPushButton::clicked,this,[this](){
        Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
        if(pCurRobot)
        {
            pCurRobot->sentryDestance();
            m_bGetLaser = true;
        }
    });

    m_pSoundLab = new QLabel(this);
    m_pSoundLab->setStyleSheet(QString("QLabel{"
                                       "background-color:transparent;"
                                       "color:#FF0000;"
                                       "font:%1px \"微软雅黑\"; "
                                       "border: 0px; "
                                       "}").arg(int(18*g_xScale)));
    m_pSoundLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    m_pSoundLab->setFixedSize(300*g_xScale,35*g_xScale);
    Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
    if(pCurRobot)
    {
        m_bGetRet = false;
        m_bGetLaser = false;
        connect(pCurRobot,&Robot::sentrySoundChanged,this,[this](int angle){m_pSoundLab->setText(QString("主麦阵角度：%1°").arg(angle));} );
        connect(pCurRobot,&Robot::sentryIndifyChanged,this,&RtspWidget::onSentryIndifyChanged,Qt::UniqueConnection);
        connect(pCurRobot,&Robot::sentryDistanceChanged,this,&RtspWidget::onSentryDistanceChanged,Qt::UniqueConnection);
    }
    connect(RobotList::getInstance(), &RobotList::curRobotChanged,this,[&](Robot * pCurRobot, Robot * pLastRobot){
        m_pSoundLab->setText("");
        if(pLastRobot)
            disconnect(pLastRobot,NULL, this,NULL);
        if(pCurRobot)
        {
            m_bGetRet = false;
            m_bGetLaser = false;
            connect(pCurRobot,&Robot::sentrySoundChanged,this,[this](int angle){m_pSoundLab->setText(QString("主麦阵角度：%1°").arg(angle));} );
            connect(pCurRobot,&Robot::sentryIndifyChanged,this,&RtspWidget::onSentryIndifyChanged,Qt::UniqueConnection);
            connect(pCurRobot,&Robot::sentryDistanceChanged,this,&RtspWidget::onSentryDistanceChanged,Qt::UniqueConnection);
        }
    });
    m_pSoundLab->setText("");
    QVBoxLayout *ctrlLayout = new QVBoxLayout(m_pSentryWidget);

    ctrlLayout->setMargin(0);
    ctrlLayout->setSpacing(20*g_yScale);

    ctrlLayout->addStretch();
    ctrlLayout->addWidget(m_pIdentifyBtn);
    ctrlLayout->addWidget(m_pTrackBtn);
    ctrlLayout->addWidget(m_pGetRetBtn);
    ctrlLayout->addWidget(m_pLaserBtn);
    m_pSentryWidget->raise();
}

RtspWidget::~RtspWidget()
{
    stopVideo(true);
}


void RtspWidget::startPlay()
{
    m_bPlaying = true;
    m_bPlaySucc = false;
    m_bMute = false;
    if(m_rtspThread.isRunning())
    {
        m_rtspThread.quit();
        if(!m_rtspThread.wait(1000))
            m_rtspThread.terminate();
    }
    m_rtspThread.start();
    update();
}

void RtspWidget::stopVideo(bool bSync)
{
    m_bPlaying = false;
    update();
    m_rtspThread.quit();
    if(bSync)
        m_rtspThread.wait();
}

void RtspWidget::takePhoto()
{
    if(!m_frame.isNull() && m_bPlaying)
    {
        m_lockFrame.lock();
        QString filePath = getPhotoPath() + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + ".png";
        m_frame.save(filePath);
        m_lockFrame.unlock();
        onTakePhoto(filePath);
        OPERATE_LOG("截图成功");
    }
    else
        OPERATE_LOG("截图失败：无法获取视频画面");

}

bool RtspWidget::startRecording()
{
    if(m_rtspThread.isRunning() && m_bPlaying)
    {
        m_rtspThread.setRecording(true);
        if(!m_bRecording)
        {
            m_pVideoBtn->setStyleSheet(
                "QPushButton{ "
                "  background-color:transparent;"
                "   border-image: url(:/images/video_record_2.png); "
                "} ");
            m_pRecordLab->setText("00:00:00");
            m_pRecordTimer->start(1000);

            OPERATE_LOG("开始录制视频");
            m_bRecording = true;
        }
    }
    return true;
}

bool RtspWidget::stopRecording(bool bSync)
{
    Q_UNUSED(bSync)
    m_rtspThread.setRecording(false);
    m_bRecording = false;
    m_pVideoBtn->setStyleSheet(
        "QPushButton{ "
        "  background-color:transparent;"
        "   border-image: url(:/images/video_record.png); "
        "} "
        "QPushButton:pressed{"
        "  border-image: url(:/images/video_record_pressed.png);"
        "}");
    m_pRecordLab->setText("");
    if(m_pRecordTimer)
        m_pRecordTimer->stop();
    m_nRecordSeconds = 0;
    OPERATE_LOG("停止录制视频");
    return true;
}

void RtspWidget::setMute(bool bMute)
{
    m_bMute = bMute;
}

void RtspWidget::setUrl(QString strUrl)
{
    m_rtspThread.setUrl(strUrl);
    VideoBase::setUrl(strUrl);
}

void RtspWidget::setShowMax(bool newShowMax)
{
    bool bShowSentry = false;
    if(newShowMax)
    {
        Robot * pCurRobot = RobotList::getInstance()->getCurRobot();
        if(pCurRobot->headType() == HEAD_SENTRY)
            bShowSentry = true;
    }
    if(bShowSentry)
    {
        m_pSentryWidget->show();
        m_pSoundLab->show();
    }
    else
    {
        m_pSentryWidget->hide();
        m_pSoundLab->hide();
    }
    VideoBase::setShowMax(newShowMax);
}

void RtspWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    // Fill the background with black color
    painter.fillRect(this->rect(), Qt::black);

    // Check if m_Frame is valid
    if (!m_frame.isNull() && m_bPlaySucc)
    {
        // Calculate the aspect ratio-preserving rectangle
        QSize frameSize = m_frame.size();
        QSize widgetSize = this->size();
        QRect targetRect = QRect(QPoint(0, 0), frameSize.scaled(widgetSize, Qt::KeepAspectRatio));
        targetRect.moveCenter(this->rect().center());

        // Draw the frame
        m_lockFrame.lock();
        painter.drawImage(targetRect, m_frame);
        m_lockFrame.unlock();
    }
    VideoBase::paintEvent(event);
}

void RtspWidget::resizeEvent(QResizeEvent *event)
{
    m_pSentryWidget->setGeometry(width() - 70*g_xScale,0,60*g_xScale,height() - 60 * g_xScale);
    m_pSoundLab->move(width() - m_pSoundLab->width()-5, height()- m_pSoundLab->height()-5);
    VideoBase::resizeEvent(event);
}

QString RtspWidget::getDestType(int destType)
{
    switch (destType) {
    case 0:
        return "单目标";
        break;
    case 1:
        return "有前目标";
        break;
    case 2:
        return "有后目标";
        break;
    case 3:
        return "有前目标与后目标";
        break;
    case 4:
        return "超距";
        break;
    case 5:
        return "保留";
        break;
    default:
        return QString("未知-%1").arg(destType);
        break;
    }
}

void RtspWidget::onSentryIndifyChanged(float fieldangle, float undershootX, float undershootY, QVector<SentryDestInfo> vtDest)
{
    if(m_bGetRet)
    {
        m_bGetRet = false;
        QString str = QString("视场角:%1°\tX轴脱靶量:%2°\tY轴脱靶量:%3°")
                          .arg(QString::number(fieldangle,'f',2))
                          .arg(QString::number(undershootX,'f',2))
                          .arg(QString::number(undershootY,'f',2));

        for(int i = 0; i < vtDest.size(); ++i)
        {
            str += "\r\n";
            str += QString("编号:%1\tx:%2\ty:%3\tw:%4\th:%5\t 置信度:%6")
                       .arg(QString::number(i+1).leftJustified(2, ' '))
                       .arg(QString::number(vtDest[i].nX).leftJustified(3, ' '))
                       .arg(QString::number(vtDest[i].nY).leftJustified(3, ' '))
                       .arg(QString::number(vtDest[i].nW).leftJustified(3, ' '))
                       .arg(QString::number(vtDest[i].nH).leftJustified(3, ' '))
                       .arg(QString::number(vtDest[i].fDegree, 'f', 2));
        }
        information(MainWindow::getInstance(),str);
    }
}

void RtspWidget::onSentryDistanceChanged(int destType, int destNum, float distance)
{
    if(m_bGetLaser)
    {
        m_bGetLaser = false;
        information(MainWindow::getInstance(),QString("测距结果:%1\t测距编号:%2\t测距值:%3m")
                                                   .arg(getDestType(destType)).arg(destNum).arg(QString::number(distance,'f',2)));

    }

}
